package com.kds.smarthome.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.kds.smarthome.controller.vo.FunctionImportVO;
import com.kds.smarthome.entity.Function;
import com.kds.smarthome.service.FunctionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

/**
 * 功能点Excel导入监听器
 */
@Slf4j
public class FunctionImportListener extends AnalysisEventListener<FunctionImportVO> {

    private final FunctionService functionService;
    private final List<Function> functionList = new ArrayList<>();
    private final List<Map<String, Object>> errorList = new ArrayList<>();
    private final Set<String> existingFids = new HashSet<>();
    private int successCount = 0;
    private int failCount = 0;
    private int skipCount = 0;

    public FunctionImportListener(FunctionService functionService) {
        this.functionService = functionService;
    }

    @Override
    public void invoke(FunctionImportVO data, AnalysisContext context) {
        try {
            int rowIndex = context.readRowHolder().getRowIndex() + 1;
            Map<String, Object> error = new HashMap<>();
            error.put("rowIndex", rowIndex);
            error.put("data", data);

            // 数据校验
            if (data.getBuildingCode() == null || data.getBuildingCode().trim().isEmpty()) {
                error.put("error", "建筑编码不能为空");
                errorList.add(error);
                failCount++;
                return;
            }
            if (data.getGatewayCode() == null || data.getGatewayCode().trim().isEmpty()) {
                error.put("error", "网关编码不能为空");
                errorList.add(error);
                failCount++;
                return;
            }
            if (data.getFunctionCode() == null || data.getFunctionCode().trim().isEmpty()) {
                error.put("error", "功能点编码不能为空");
                errorList.add(error);
                failCount++;
                return;
            }

            // 转换为Function实体
            Function function = new Function();
            BeanUtils.copyProperties(data, function);
            
            // 生成fid
            String fid = data.getBuildingCode() + "_" + data.getGatewayCode() + "_" + data.getFunctionCode();
            function.setFid(fid);
            
            // 检查fid是否已存在
            Function existingFunction = functionService.findByFid(fid);
            if (existingFunction != null) {
                existingFids.add(fid);
                skipCount++;
                return;
            }
            
            // 设置默认值
            if (function.getRatio() == null) {
                function.setRatio(1.0);
            }
            if (function.getDisabled() == null) {
                function.setDisabled(0);
            }

            functionList.add(function);
            successCount++;
        } catch (Exception e) {
            log.error("Excel导入处理失败", e);
            Map<String, Object> error = new HashMap<>();
            error.put("rowIndex", context.readRowHolder().getRowIndex() + 1);
            error.put("data", data);
            error.put("error", "处理失败：" + e.getMessage());
            errorList.add(error);
            failCount++;
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        try {
            // 批量保存数据
            if (!functionList.isEmpty()) {
                functionService.batchCreate(functionList);
            }
        } catch (Exception e) {
            log.error("批量保存功能点数据失败", e);
            Map<String, Object> error = new HashMap<>();
            error.put("error", "批量保存失败：" + e.getMessage());
            errorList.add(error);
        }
    }

    public List<Map<String, Object>> getErrorList() {
        return errorList;
    }

    public int getSuccessCount() {
        return successCount;
    }

    public int getFailCount() {
        return failCount;
    }

    public int getSkipCount() {
        return skipCount;
    }

    public Set<String> getExistingFids() {
        return existingFids;
    }
} 